package fr.umlv.metadata;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.ResourceBundle;
import java.util.logging.Level;

import org.apache.chemistry.opencmis.client.api.ObjectType;
import org.apache.chemistry.opencmis.client.api.Tree;
import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
import org.jdesktop.swingx.JXErrorPane;
import org.jdesktop.swingx.error.ErrorInfo;

import fr.umlv.authentication.SessionHandler;
import fr.umlv.model.ClientModel;
import fr.umlv.model.ClientSession;

// TODO: Auto-generated Javadoc
/**
 * The Class AspectUtils.
 */
public class AspectUtils {

	/** The aspect names. */
	private List<String> aspectNames;
	
	/** The client session. */
	private ClientSession clientSession;
	
	/** The aspect to get. */
	private List<String> aspectToGet ;
	
	/** The map. */
	private Map<String,ObjectType> map;
	
	/** The bundle. */
	private ResourceBundle bundle = ResourceBundle.getBundle("fr.umlv.metadata.MetadataPage");

	/**
	 * Instantiates a new aspect utils.
	 */
	public AspectUtils() {
		this.clientSession = SessionHandler.getClientSession();
		this.aspectToGet = initializeAspectToGet();
		map = new HashMap<String, ObjectType>();
		init();
	}

	/**
	 * Initialize aspect to get.
	 *
	 * @return the list
	 */
	public List<String> initializeAspectToGet(){
		BufferedReader buf = null;
		List<String> list = new ArrayList<String>();
		String ligne;
		try
		{
			buf = new BufferedReader
			(new InputStreamReader(getClass().getResource(bundle.getString("pathAllAspects.text")).openStream()));
			while ((ligne = buf.readLine()) != null)
				list.add(ligne);
			buf.close();
		}
		catch(FileNotFoundException e)
		{
			JXErrorPane.showDialog(null, new ErrorInfo(e.getMessage(), 
					e.getMessage(), 
					null, "FileNotFoundException", e, Level.WARNING, null)); 
			
		} catch (IOException e) {
			e.printStackTrace();
		}

		return list;

	}

	/**
	 * Inits the.
	 *
	 * @return the map
	 */
	public Map<String,ObjectType> init(){

		aspectNames = new ArrayList<String>();

		ClientModel model = new ClientModel();

		model.setClientSession(clientSession);

		try {
			
			model.loadFolder(clientSession.getSession().getRepositoryInfo().getRootFolderId(), false);
			
			List<Tree<ObjectType>> types =clientSession.getSession().getTypeDescendants("cmis:policy", -1, true);

			for (Tree<ObjectType> tt : types) {

				if(aspectToGet.contains(tt.getItem().getId())){

					map.put(tt.getItem().getDisplayName(),tt.getItem());
					aspectNames.add(tt.getItem().getDisplayName());
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return map;
	}

	/**
	 * Gets the aspect names.
	 *
	 * @return the aspect names
	 */
	public List<String> getAspectNames() {
		return aspectNames;
	}

	/**
	 * Gets the fields.
	 *
	 * @param name the name
	 * @return the fields
	 */
	public List<String> getFields(String name){

		Map<String,PropertyDefinition<?>> property = map.get(name).getPropertyDefinitions();
		List<String> list = new ArrayList<String>();

		for(Entry<String,PropertyDefinition<?>> entry:property.entrySet()){
			list.add(entry.getValue().getDisplayName());
		}
		return list;
	}

	/**
	 * Gets the iD.
	 *
	 * @param name the name
	 * @return the iD
	 */
	public String getID(String name){
		return map.get(name).getId();
	}

	/**
	 * Gets the name.
	 *
	 * @param idProperty the id property
	 * @return the name
	 */
	public String getName(String idProperty){

		for(Entry<String, ObjectType> entry:map.entrySet()){

			for(Entry<String, PropertyDefinition<?>> entry2:entry.getValue().getPropertyDefinitions().entrySet()){

				if(idProperty.equals(entry2.getKey())){
					return entry.getKey();
				}
			}
		}
		
		return null;
	}

	/**
	 * Gets the iD.
	 *
	 * @return the iD
	 */
	public List<String> getID(){

		List<String> list = new ArrayList<String>();

		for(Entry<String, ObjectType> entry: map.entrySet()){

			list.add(entry.getValue().getId());
		}

		return list;
	}

	/**
	 * Gets the properties.
	 *
	 * @param name the name
	 * @return the properties
	 */
	public Map<String,PropertyDefinition<?>> getProperties(String name){

		return map.get(name).getPropertyDefinitions();
	}
	
	/**
	 * Gets the properties as list.
	 *
	 * @param name the name
	 * @return the properties as list
	 */
	public List<PropertyDefinition<?>> getPropertiesAsList(String name){

		Map<String,PropertyDefinition<?>> property = map.get(name).getPropertyDefinitions();
		
		List<PropertyDefinition<?>> list = new ArrayList<PropertyDefinition<?>>();

		for(Entry<String,PropertyDefinition<?>> entry:property.entrySet()){
			list.add(entry.getValue());
		}
	
		return list;
	}
}
